package control.render;

import java.awt.Color;
import java.awt.image.BufferedImage;

import data.base.RenderColor;

public class MonteCarloImage {
  private BufferedImage bImage;
  private BufferedImage sampleMap;
  private long samples = 0;
  
  public MonteCarloImage(BufferedImage bImage){
    this.bImage = bImage;
    init();
  }
  
  private void init(){
    sampleMap = new BufferedImage(bImage.getWidth(), bImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
    for(int y = 0; y < bImage.getHeight(); y++)
      for(int x = 0; x < bImage.getWidth(); x++)
        sampleMap.setRGB(x, y, 0);
  }
  
  public void addSample(double x, double y, Color col){
    addSample(1, (int)x, (int)y, new RenderColor(col));
  }
  
  public void addQuadSample(double x, double y, Color col){
    RenderColor c = new RenderColor(col);
    int x1 = (int)x;
    int y1 = (int)y;
    
    double uFactor = x - x1;
    double vFactor = y - y1;

    addSample((1 - uFactor) * (1 - vFactor), x1, y1, c);
    addSample((uFactor) * (1 - vFactor), x1 + 1, y1, c);
    addSample((1 - uFactor) * (vFactor), x1, y1 + 1, c);
    addSample((uFactor) * (vFactor), x1 + 1, y1 + 1, c);
  }
  
  private void addSample(double factor, int x, int y, RenderColor cNew){
    float newSampleCount = Float.intBitsToFloat(sampleMap.getRGB(x, y)) + (float)factor;
    double sampleAlpha = 1d / newSampleCount * factor;
    
    RenderColor cOld = new RenderColor(bImage.getRGB(x, y));
    cOld.mixWithColor(cNew, sampleAlpha);

    bImage.setRGB(x, y, cOld.getColor().getRGB());
    sampleMap.setRGB(x, y, Float.floatToIntBits(newSampleCount));
    samples++;
  }
      
  public int getWidth(){
    return bImage.getWidth();
  }
  
  public int getHeight(){
    return bImage.getHeight();
  }
  
  public double getSamplesPerPixel(){
    int pixels = bImage.getWidth() * bImage.getHeight();
    return ((int)(samples * 100 / pixels)) / 100d;
  }
}
